package worker

import (
	"fmt"
	"strconv"
	"svvenus/vpub/constants"
	"svvenus/znet"
	"svvenus/znet/zpack"
	"svvenus/znet/zpb"
	"svvenus/znet/ztcp"
)

var (
	TcpChan        = make(chan *znet.Request, 1024)       //消息队列
	TcpBinds       = make(map[uint16]func(*znet.Request)) //处理列表
	TcpBindsSpeedy = make(map[uint16]func(*znet.Request)) //即时处理列表
)

// TcpWorker
// @Description: tcp服务
type TcpWorker struct {
	TcpServer *ztcp.TcpServer
}

// NewTcpWorker 创建
// @param onConnStart
// @param onConnStop
// @return *TcpWorker
func NewTcpWorker(onConnStart func(conn *ztcp.TcpConnection), onConnStop func(conn *ztcp.TcpConnection)) *TcpWorker {
	sv := &TcpWorker{}
	sv.TcpServer = ztcp.NewTcpServer("0.0.0.0", constants.PortTcp)
	sv.TcpServer.OnConnStart = onConnStart
	sv.TcpServer.OnConnStop = onConnStop
	sv.TcpServer.OnMsgReceive = sv.OnMsgReceive
	return sv
}

// Start 启动
// @receiver w
// @param fnRegister
func (w *TcpWorker) Start(fnRegister func()) {
	fnRegister()
	w.TcpServer.Start()
}

// OnMsgReceive 接收到消息
// @receiver w
// @param request
func (w *TcpWorker) OnMsgReceive(conn *ztcp.TcpConnection, msg *zpack.PackBuffer) {
	//得到当前客户端请求的Request数据
	request := &znet.Request{
		Conn: conn,
		Msg:  msg,
	}
	if w.MsgHandleDoSpeedy(request) {
		return
	}
	TcpChan <- request
}

// TcpMsgHandleDo
// @Description:
// @param request
func TcpMsgHandleDo(request *znet.Request) {
	handler, ok := TcpBinds[request.GetMsgID()]
	if !ok {
		fmt.Println("Handle msgId = ", request.GetMsgID(), " is not FOUND!")
		return
	}
	//执行对应处理方法
	handler(request)
}

// MsgHandleDoSpeedy
// @Description:
// @receiver w
// @param request
// @return bool
func (w *TcpWorker) MsgHandleDoSpeedy(request *znet.Request) bool {
	handler, ok := TcpBindsSpeedy[request.GetMsgID()]
	if ok {
		//执行对应处理方法
		handler(request)
		return true
	}
	return false
}

// TcpWorkerBind 绑定
// @param pid
// @param handle
func TcpWorkerBind(pid zpb.EPid, handle func(*znet.Request)) {
	msgId := uint16(pid)
	//1 判断当前msg绑定的API处理方法是否已经存在
	if _, ok := TcpBinds[msgId]; ok {
		panic("repeated api , pid = " + strconv.Itoa(int(pid)))
	}
	//2 添加msg与api的绑定关系
	TcpBinds[msgId] = handle
	fmt.Println("TcpWorkerBind pid = ", pid, " msgId = ", msgId)
}

// TcpWorkerBindSpeedy
// @Description:
// @param pid
// @param handle
func TcpWorkerBindSpeedy(pid zpb.EPid, handle func(*znet.Request)) {
	msgId := uint16(pid)
	//1 判断当前msg绑定的API处理方法是否已经存在
	if _, ok := TcpBindsSpeedy[msgId]; ok {
		panic("repeated api , pid = " + strconv.Itoa(int(pid)))
	}
	//2 添加msg与api的绑定关系
	TcpBindsSpeedy[msgId] = handle
	fmt.Println("TcpWorkerBindSpeedy pid = ", pid, " msgId = ", msgId)
}
